package com.niodata.dp.expression.function.date;

import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

public class DateStrAddFunction extends AbstractFunction {

  @Override
  public String getName() {
    return "date.str_add";
  }

  /**
   * date add function.
   *
   * @param env env
   * @param date date
   * @param interval interval
   * @param unit unit
   * @param srcFmt src date format
   * @param outFmt output date format
   * @return add date
   */
  public AviatorObject call(Map<String, Object> env, AviatorObject date, AviatorObject interval,
        AviatorObject unit, AviatorObject srcFmt, AviatorObject outFmt) {
    String src = FunctionUtils.getStringValue(date, env);
    SimpleDateFormat srcFormat = new SimpleDateFormat(FunctionUtils.getStringValue(srcFmt, env));
    Date dv = null;
    try {
      dv = srcFormat.parse(src);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    int intv = FunctionUtils.getNumberValue(interval, env).intValue();
    String unitv = FunctionUtils.getStringValue(unit, env);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dv);
    switch (unitv) {
      case "MIN":
        calendar.add(Calendar.MINUTE, intv);
        break;
      case "HOUR":
        calendar.add(Calendar.HOUR, intv);
        break;
      case "SEC":
        calendar.add(Calendar.SECOND, intv);
        break;
      case "DAY":
        calendar.add(Calendar.DAY_OF_YEAR, intv);
        break;
      case "MON":
        calendar.add(Calendar.MONTH, intv);
        break;
      case "YEAR":
        calendar.add(Calendar.YEAR, intv);
        break;
      default:
        throw new RuntimeException("bad unit:" + unitv);
    }
    dv = calendar.getTime();
    SimpleDateFormat outFormat = new SimpleDateFormat(FunctionUtils.getStringValue(outFmt, env));
    String outTime = outFormat.format(dv);
    return FunctionUtils.wrapReturn(outTime);
  }

  /**
   * date add function.
   *
   * @param env env
   * @param date date
   * @param interval interval
   * @param unit unit
   * @param srcFmt src date format
   * @return add date
   */
  public AviatorObject call(Map<String, Object> env, AviatorObject date, AviatorObject interval,
        AviatorObject unit, AviatorObject srcFmt) {
    String src = FunctionUtils.getStringValue(date, env);
    SimpleDateFormat srcFormat = new SimpleDateFormat(FunctionUtils.getStringValue(srcFmt, env));
    Date dv = null;
    try {
      dv = srcFormat.parse(src);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    int intv = FunctionUtils.getNumberValue(interval, env).intValue();
    String unitv = FunctionUtils.getStringValue(unit, env);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dv);
    switch (unitv) {
      case "MIN":
        calendar.add(Calendar.MINUTE, intv);
        break;
      case "HOUR":
        calendar.add(Calendar.HOUR, intv);
        break;
      case "SEC":
        calendar.add(Calendar.SECOND, intv);
        break;
      case "DAY":
        calendar.add(Calendar.DAY_OF_YEAR, intv);
        break;
      case "MON":
        calendar.add(Calendar.MONTH, intv);
        break;
      case "YEAR":
        calendar.add(Calendar.YEAR, intv);
        break;
      default:
        throw new RuntimeException("bad unit:" + unitv);
    }
    dv = calendar.getTime();
    String dvStr = srcFormat.format(dv);
    return FunctionUtils.wrapReturn(dvStr);
  }
}
